package com.xh.xyzp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xh.xyzp.common.constant.UserContext;
import com.xh.xyzp.common.domain.vo.resp.PageResp;
import com.xh.xyzp.common.enums.CommonStatusTypeEnum;
import com.xh.xyzp.domain.entity.User;
import com.xh.xyzp.domain.vo.*;
import com.xh.xyzp.enums.UserTypeEnum;
import com.xh.xyzp.mapper.UserMapper;
import com.xh.xyzp.service.CompanyService;
import com.xh.xyzp.service.UserService;
import com.xh.xyzp.util.RedisUtil;
import com.xh.xyzp.util.SnowFlakeIdWorker;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Author: xianghao
 * @Description:
 * @Date: 2025-04-12  11:12
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CompanyService companyService;

    private static final String SECRET = "eyJqdGkiOiI0MDQiLCJzdWIiOiLpgqLnq4vosbkiL";

    @Override
    public LoginResp login(LoginReq req) {
        req.checkParams();
        User user = getByUsername(req.getUsername());
        if (Objects.isNull(user)) {
            throw new ApiException("账号或者密码不正确");
        }
        if (!user.getPassword().equals(DigestUtils.md5DigestAsHex(req.getPassword().getBytes()))) {
            throw new ApiException("账号或者密码不正确");
        }
        if (Objects.nonNull(req.getType())) {
            if (!req.getType().equals(user.getType())) {
                throw new ApiException("账号或者密码不正确");
            }
        } else {
            if (!UserTypeEnum.USER.getKey().equals(user.getType())) {
                throw new ApiException("账号或者密码不正确");
            }
        }
        String token = createToken(user.getId());
        RedisUtil.set(token, user, 3, TimeUnit.HOURS);
        return LoginResp.builder()
                .token(token)
                .user(user)
                .build();
    }

    public static String createToken(Long userId) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        return Jwts.builder()
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .setClaims(map)
                .compact();
    }

    private User getByUsername(String username) {
        User user = lambdaQuery().eq(User::getUsername, username).one();
        if (Objects.isNull(user)) {
            return null;
        }
        if (!CommonStatusTypeEnum.NORMAL.getKey().equals(user.getStatus())) {
            throw new ApiException("用户已被禁用");
        }
        return user;
    }

    @Override
    public void register(RegisterReq req) {
        req.checkParams();
        User user = getByUsername(req.getUsername());
        String code = RedisUtil.get("register_email_code:" + req.getEmail());
        if (StrUtil.isNotEmpty(code) && !req.getCode().equals(code)) {
            throw new ApiException("验证码错误");
        }
        if(Objects.nonNull(user)) {
            throw new ApiException("账号已存在");
        }
        user = new User(
                new SnowFlakeIdWorker(0, 1).nextId(),
                req.getUsername(),
                DigestUtils.md5DigestAsHex(req.getPassword().getBytes()),
                "用户" + RandomUtil.randomNumbers(6),
                "暂无自我介绍",
                "https://q1.qlogo.cn/g?b=qq&nk=2045718969&s=640",
                Objects.isNull(req.getType()) ? UserTypeEnum.USER.getKey() : req.getType()
        );
        save(user);
        if (UserTypeEnum.COMPANY.getKey().equals(user.getType())) {
            UserContext.setUser(user);
            companyService.submit(new CompanySubmitReq(req.getCompanyName(), req.getCompanyAddress(),
                    req.getCompanyAvatar()));
        }
    }

    @Override
    public User getUserInfo(Long userId) {
        if (Objects.isNull(userId)) {
            throw new ApiException("用户ID不能为空");
        }
        User user = lambdaQuery().eq(User::getId, userId).one();
        if (!CommonStatusTypeEnum.NORMAL.getKey().equals(user.getStatus())) {
            throw new ApiException("用户已被禁用");
        }
        return user;
    }

    @Override
    public PageResp<User> getList(UserListReq req) {
        req.checkParams();
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotEmpty(req.getUsername())) {
            lambdaQueryWrapper.like(User::getUsername, req.getUsername());
        }
        if (StrUtil.isNotEmpty(req.getNickname())) {
            lambdaQueryWrapper.like(User::getNickname, req.getNickname());
        }
        if (Objects.nonNull(req.getStatus())) {
            lambdaQueryWrapper.eq(User::getStatus, req.getStatus());
        }
        Page<User> userPage = userMapper.selectPage(new Page<>(req.getCurrPage(), req.getPageSize()), lambdaQueryWrapper);
        return PageResp.<User>builder()
                .list(userPage.getRecords())
                .total(userPage.getTotal())
                .build();
    }

    @Override
    public User submitUserInfo(User user) {
        user.checkParams();
        Long userId = user.getId();
        if (Objects.isNull(user.getId())) {
            userId = UserContext.getUser().getId();
        }
        User find = userMapper.selectById(userId);
        BeanUtils.copyProperties(user, find);
        updateById(find);
        return find;
    }

    @Override
    public void submitUserInfoByAdmin(UserAdminSubmitReq req) {
        User findUser = getByUsername(req.getUsername());
        if(Objects.nonNull(findUser)) {
            throw new ApiException("账号已存在");
        }
        User user = new User(
                new SnowFlakeIdWorker(0, 1).nextId(),
                req.getUsername(),
                DigestUtils.md5DigestAsHex(req.getPassword().getBytes()),
                req.getNickname(),
                req.getIntroduce(),
                "https://q1.qlogo.cn/g?b=qq&nk=2045718969&s=640",
                UserTypeEnum.USER.getKey()
        );
        save(user);
    }
}
